/***************************************************************************//**
 * @file     csa37f7x_tim.h
 * @version  V1.0.0
 * @author   cs2040
 * @date     2020-09-26 PM
 * @brief    该文件包含了TIM0各功能参数的定义和函数接口声明
 * 
 * @copyright Copyright (C) 2020 Chipsea Technologies Corp. All rights reserved.
 ****************************************************************************
 * @attention
 *  硬件平台: CSA37F70 评估板V1.0 \n
 *  SDK版本： CSA37F7X_SDK_1.0.0
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date        <th>Version  <th>Author    <th>Description
 * <tr><td>2020-09-26  <td>1.0.0    <td>Chipsea MCU Group  <td>创建初始版本
 * </table>
 *
 *****************************************************************************/

#ifndef __CSA37F7X_TIM_H__
#define __CSA37F7X_TIM_H__

// Include external header file.
#include "csa37f7x.h"

#ifdef __cplusplus
extern "C" {
#endif

/** @addtogroup TIM0 通用定时器(TIM0) 
 通用定时器（TIM0）包含一个由可编程预分频器驱动的 16 位自动装载计数器。
该定时器有多种用途，可用于测量输入信号的脉冲宽度（输入捕获）或产生输出波形（输出比较、 PWM）。
使用定时器预分频器和时钟控制预分频器，可以对脉冲宽度和波形周期进行从几个微秒到几个毫秒的调节。。<br>
###特性: 
    - 16 位向上自动装载计数器
    - 16 位可编程预分频器能对计数器的输入时钟进行 1 ~ 65536（分频系数可实时修改）分频
    - 输入捕获
    - 输出比较
    - 计数器更新，输入捕获，输出比较均可产生中断请求
  @{
*/


/**
 * @brief  宏定义检查指定定时器时钟分频因子式选择
 */
typedef enum
{
    TIM_CKDIV_DIV1        =         ((uint16_t)0x0000),          /*!<定时器时钟分频因子是1 */
    TIM_CKDIV_DIV2        =         ((uint16_t)0x0100),          /*!<定时器时钟分频因子是2 */
    TIM_CKDIV_DIV4        =         ((uint16_t)0x0200),          /*!<定时器时钟分频因子是4 */
} tim_clk_div_t; 

/**
 * @brief  定时器0配置结构体
 */
typedef struct
{
    uint16_t time_divide;                                           /*!<定时器分频设置:0~0xFFFF */
    uint16_t time_period;                                           /*!<定时器自动装载值:0~0xFFFF */
    tim_clk_div_t clock_divide;                                     /*!<定义在定时器时钟(CK_INT)频率、死区时间和由死区发生器与数字滤波器所用的采样时钟之间的分频比例 */
} timer_config_t;       

/**
  * @brief  宏定义检定定时器模式选择
  */
typedef enum
{
    TIM_CHxOCMSEL_TIMING          =       ((uint16_t)0x0000),
    TIM_CHxOCMSEL_ACTIVE          =       ((uint16_t)0x0010),
    TIM_CHxOCMSEL_INACTIVE        =       ((uint16_t)0x0020),
    TIM_CHxOCMSEL_TOGGLE          =       ((uint16_t)0x0030),
    TIM_CHxOCMSEL_PWM1            =       ((uint16_t)0x0060),
    TIM_CHxOCMSEL_PWM2            =       ((uint16_t)0x0070),
}timer_chxocmsel_mode_t;

/** 
  * @brief 宏定义检查定时器输出比较状态选择
  */
typedef enum
{
    TIM_CHx_OUTPUT_DISABLE     =       ((uint16_t)0x0000),        /*!<关闭定时器输入/捕获1输出 */ 
    TIM_CHx_OUTPUT_ENABLE      =       ((uint16_t)0x0001),        /*!<使能定时器输入/捕获1输出 */ 
}timer_out_status_t;

/** 
  * @brief 宏定义检查定时器输出极性选择
  */
typedef enum
{
    TIM_CHxCCP_POLARITY_HIGH     =    ((uint16_t)0x0000),        /*!<捕获比较极性为高电平有效 */
    TIM_CHxCCP_POLARITY_LOW      =    ((uint16_t)0x0002),        /*!<捕获比较极性为低电平有效 */
}timer_polarity_t;
                                             
/**
 * @brief  定时器0比较结构体
 */
typedef struct
{
    timer_chxocmsel_mode_t time_mode;                                             /*!< 指定定时器模式 */
    timer_out_status_t output_state;                                          /*!< 指定定时器输出比较状态 */
    uint16_t timer_pulse;                                           /*!< 捕获/比较值设置:0~0xFFFF */
    timer_polarity_t output_polarity;                                       /*!< 指定定时器输出极性 */
} timer_compare_t;


/** 
  * @brief 宏定义检查定时器产生更新事件模式
  */
typedef enum
{
    TIM_PDIV_MODE_UPDATE       =  ((uint16_t)0x0000),            /*!< 无动作 */
    TIM_PDIV_MODE_IMMEDIATE    =  ((uint16_t)0x0001),            /*!< 重新初始化计数器，并产生一个更新事件 */
}timer_updata_generation_t;


/**
  * @brief 宏定义检查定时器通道选择
  */
typedef enum
{
    TIM_CHANNEL_NUM_1    =  ((uint16_t)0x0000),                  /*!< 定时器通道1 */
    TIM_CHANNEL_NUM_2    =  ((uint16_t)0x0004),                  /*!< 定时器通道2 */
    TIM_CHANNEL_NUM_3    =  ((uint16_t)0x0008),                  /*!< 定时器通道3 */ 
    TIM_CHANNEL_NUM_4    =  ((uint16_t)0x000C),                  /*!< 定时器通道4 */ 
}timer_channnel_t;
                                       
/**   
  * @brief 宏定义检查定时器通道输入捕获极性选择
  */
typedef enum
{
TIM_CHxIC_POLARITY_RISING          =   ((uint16_t)0x0000),    /*!< 电路对TI1FP1上升沿敏感 */
TIM_CHxIC_POLARITY_FALLING         =   ((uint16_t)0x0002),    /*!< 电路对TI1FP1下降沿敏感 */
TIM_CHxIC_POLARITY_BOTH_EDGE       =   ((uint16_t)0x000A),    /*!< 电路对TI1FP1上升/下降沿敏感 */
}timer_chic_polarrity_t;
                                         
/** 
  * @brief 宏定义检查定时器通道输入捕获选择
  */
typedef enum
{
    TIM_CHIC_SEL_DIRECT_OUTR   =       ((uint16_t)0x0000),       /*!< 捕获/比较1通道被配置为输出 */
    TIM_CHIC_SEL_DIRECT_INTR   =     ((uint16_t)0x0001),         /*!< 捕获/比较1通道被配置为输入 */
}timer_chic_sel_direction_t;
           
/** 
  * @brief 宏定义检查定时器通道输入捕获分频选择
  */
typedef enum
{
    TIM_CHIC_PREDIVIDE_DIV1         =        ((uint16_t)0x0000), /*!<无预分频器 */
    TIM_CHIC_PREDIVIDE_DIV2         =        ((uint16_t)0x0004), /*!< 每2个事件触发一次捕获 */
    TIM_CHIC_PREDIVIDE_DIV4         =        ((uint16_t)0x0008), /*!< 每4个事件触发一次捕获 */
    TIM_CHIC_PREDIVIDE_DIV8         =        ((uint16_t)0x000C), /*!< 每8个事件触发一次捕获 */
}timer_chic_pdiv_t;
                                         
 /** 
  * @brief 宏定义检查定时器输入捕获滤波值选择
  */
#define TIM_CHxIC_FILTER_CHECK(value) ((value) <= 0xF) 

/**
 * @brief  定时器0捕获结构体
 */
typedef struct
{
    timer_channnel_t time_channel;                                          /*!< 指定定时器通道 */
    timer_chic_polarrity_t input_polarity;                                        /*!< 指定定时器输入捕获极性 */
    timer_chic_sel_direction_t input_select;                                          /*!< 指定定时器输入捕获选择 */
    timer_chic_pdiv_t input_predivide;                                       /*!< 指定定时器输入捕获分频 */
    uint16_t input_filter;                                          /*!< 指定定时器输入捕获1滤波器 */
} timer_capture_t; 
  
  
/**
  * @brief 宏定义检查定时器请求中断源选择
  */
typedef enum
{
    TIM_UPDATE_SEL_GLOBAL      =     ((uint16_t)0x0000),         /*!< 计数器溢出或设置UG位产生更新中断请求 */
    TIM_UPDATE_SEL_REGULAR     =     ((uint16_t)0x0001),         /*!< 只有计数器溢出才产生一个更新中断 */
}timer_upd_requ_source_t;
  
/** 
  * @brief 宏定义检查定时器脉冲模式选择
  */
typedef enum
{
    TIM_PULSE_MODE_SINGLE       =   ((uint16_t)0x0008),          /*!< 单脉冲模式 */
    TIM_PULSE_MODE_REPETITIVE   =   ((uint16_t)0x0000),          /*!< 重复模式 */
}timer_pulse_mode_t;

/**
  * @brief 宏定义检查定时器0输出参考信号的强制操作选择
  */
typedef enum
{
    TIM_CHxOCMSEL_FORCED_ACTIVE        =   ((uint16_t)0x0050),   /*!< 强制为有效电平，强制OC1REF为高  */
    TIM_CHxOCMSEL_FORCED_INACTIVE      =   ((uint16_t)0x0040),   /*!< 强制为无效电平，强制OC1REF为低  */
}timer_chxocmsel_force_t;
                                          
/** 
  * @brief 宏定义检查通道输出比较预装载使能选择
  */
typedef enum
{
    TIM_CHxOC_PRELOAD_ENABLE       =       ((uint16_t)0x0008),   /*!< 通道输出比较预装载使能  */
    TIM_CHxOC_PRELOAD_DISABLE      =       ((uint16_t)0x0000),   /*!< 关闭通道输出比较预装载  */
}timer_choc_preload_t;                                     
                                          
/** 
  * @brief 宏定义检查定时器0通道输出比较快速模式使能选择
  */
typedef enum
{
    TIM_CHxOC_FAST_ENABLE          =       ((uint16_t)0x0004),   /*!< 通道输出比较快速模式使能 */
    TIM_CHxOC_FAST_DISABLE         =       ((uint16_t)0x0000),   /*!< 禁止通道输出比较快速模式 */
}timer_choc_fast_t;
                                  
/** 
  * @brief 宏定义检查定时器0通道捕获比较使能选择
  */
typedef enum
{
    TIM_CHxCC_ENABLE          =       ((uint16_t)0x0001),        /*!< 使能定时器通道捕获比较 */
    TIM_CHxCC_DISABLE         =       ((uint16_t)0x0000),        /*!< 禁止定时器通道捕获比较 */
}timer_chcc_ctrl_t ;

/** 
  * @brief 宏定义检查定时器中断源选择
  */
typedef enum
{
    TIM_INTR_UPDATE         =            ((uint16_t)0x0001),     /*!< 更新中断 */
    TIM_INTR_CC1IE          =            ((uint16_t)0x0002),     /*!< 允许捕获/比较1中断 */
}timer_int_source_t;    
    
/** 
  * @brief 宏定义检查定时器状态标记选择
  */
typedef enum
{
    TIM_FLAG_UPDATE         =            ((uint16_t)0x0001),     /*!< 更新中断标记 */
    TIM_FLAG_CC1IE          =            ((uint16_t)0x0002),     /*!< 捕获/比较 1 中断标记 */
    TIM_FLAG_CC1OF          =            ((uint16_t)0x0200),     /*!< 捕获/比较 1 重复捕获标记 */    
}timer_flag_t;        

/** 
  * @brief 宏定义检查定时器中断事件源选择
  */
typedef enum
{
    TIM_EVENT_SOURCE_UPDATE       =     ((uint16_t)0x0001),      /*!< 产生更新事件 */
    TIM_EVENT_SOURCE_CH1          =     ((uint16_t)0x0002),      /*!< 产生捕获/比较1事件 */
}timer_event_source_t;


/**
  * @brief 宏定义检查定时器输入重映射选择
  */
typedef enum
{
    TIM0_REMAP_PORT            =         ((uint16_t)0x0000),     /*!< 定时器0通道1连接到 GPIO */
    TIM0_REMAP_MCO             =         ((uint16_t)0x0003),     /*!< 定时器0通道1连接到微控制器时钟输出 */
}timer_remap_t;

                                  

/**@brief		    重置timer0
 *
 * @return		    无
*/
void tim_def_init(void);

/**@brief		    timer0初始化
 *
 * @param[in]	    ptr_config  定时器0配置结构体
 * @return		    无
*/
void tim_timer_config(timer_config_t* ptr_config);

/**@brief		    用默认值填充timer0寄存器结构体
 *
 * @return		    无
*/
void tim_config_struct_init(timer_config_t* ptr_config);

/**@brief		    配置定时器预分频，并产生更新事件
 *
 * @param[in]	    value  指定预分频的值
 * @param[in]	    flag  定时器事件产生选择
 * @return		    无
*/
void tim_pdiv_register_config(uint16_t value, timer_updata_generation_t flag);

/**@brief		    设置timer0计数器值
 *
 * @param[in]	    value  指定计数新值
 * @return		    无
*/
void tim_counter_set(uint16_t value);

/**@brief		    设置定时器0的重装载值
 *
 * @param[in]	    value  待设置的定时器0的重装载值
 * @return		    无
*/
void tim_counter_update_set(uint16_t value);

/**@brief		    获取timer0计数值
 *
 * @return		    timer0计数值
*/
uint16_t tim_counter_get(void);

/**@brief		    获取timer0预分频的值
 *
 * @return		    timer0预分频的值
*/
uint16_t tim_pdiv_register_value_get(void);

/**@brief		    使能或禁止timer0更新事件
 *
 * @param[in]	    enable_flag  使能/禁止选择
 * @return		    无
*/
void tim_update_disable_set(enable_state_t enable_flag);

/**@brief		    选择timer0更新请求中断源
 *
 * @param[in]	    value  指定定时器更新源
 * @return		    无
*/
void tim_update_request_select(timer_upd_requ_source_t value);

/**@brief		    使能或禁止影子寄存器
 *
 * @param[in]	    enable_flag  使能/禁止选择
 * @return		    无
*/
void tim_uval_shadow_config(enable_state_t enable_flag);

/**@brief		    设置定时为单脉冲模式或者重复模式
 *
 * @param[in]	    value  单脉冲模式或者重复模式选择
 * @return		    无
*/
void tim_pulse_mode_set(timer_pulse_mode_t value);

/**@brief		    设置timer0时钟分频因子
 *
 * @param[in]	    value  设置的定时器时钟分频因子
 * @return		    无
*/
void tim_clock_division_set(tim_clk_div_t value);

/**@brief		    使能或者禁止定时器模块
 *
 * @param[in]	    enable_flag  使能/禁止选择
 * @return		    无
*/
void tim_enable_ctrl(enable_state_t enable_flag);

/**@brief		    初始化定时器通道1输出比较
 *
 * @param[in]	    ptr_compare  定时器输出比较的结构体
 * @return		    无
*/
void tim_ch1oc_init(timer_compare_t* ptr_compare);

/**@brief		    定时器0输出比较通道模式设置
 *
 * @param[in]	    channel_num  设置的定时器通道
 * @param[in]	    mode  指定输出模式
 * @return		    无
*/
void tim_choc_mode_select(timer_channnel_t channel_num, timer_chxocmsel_mode_t mode);

/**@brief		    定时器0输出比较值设置
 *
 * @param[in]	    value  比较输出值
 * @return		    无
*/
void tim_ch1cc_value_set(uint32_t value);

/**@brief		    设置通道1输出比较输出或者不输出
 *
 * @param[in]	    value  输出参考信号的强制操作
 * @return		    无
*/
void tim_ch1oc_mode_force_set(timer_chxocmsel_force_t value);

/**@brief		    使能或者禁止通道输出比较预加载值
 *
 * @param[in]	    value  使能预加载或者禁止预加载
 * @return		    无
*/
void tim_ch1oc_preload_set(timer_choc_preload_t value);

/**@brief		    通道1输出比较快速模式设置
 *
 * @param[in]	    value  使能或者禁止快速模式
 * @return		    无
*/
void tim_ch1oc_fast_set(timer_choc_fast_t value);

/**@brief		    通道1输出比较捕获极性设置 
 *
 * @param[in]	    value  指定的捕获极性
 * @return		    无
*/
void tim_ch1cc_polarity_set(timer_polarity_t value);

/**@brief		    使能或者禁止定时器通道捕获比较
 *
 * @param[in]	    channel  指定的定时器通道
 * @param[in]	    value  使能或者禁止
 * @return		    无 
*/
void tim_chcc_enable_ctrl(timer_channnel_t channel, timer_chcc_ctrl_t value);

/**@brief		    初始化输入捕获寄存器结构体
 *
 * @param[in]	    ptr_capture  输入捕获配置的结构体
 * @return		    无
*/
void tim_chic_init(timer_capture_t* ptr_capture);

/**@brief		    输入捕获寄存器结构体设为缺省
 *
 * @param[in]	    ptr_capture  输入捕获配置的结构体
 * @return		    无
*/
void tim_capture_struct_init(timer_capture_t* ptr_capture);

/**@brief		    获取定时器通道1的捕获值
 *
 * @return		    定时器通道1的捕获值
*/
uint32_t tim_ch1cc_value_get(void);

/**@brief		    设置通道1输入捕获通道的预分频
 *
 * @param[in]	    value  指定的预分频割值
 * @return		    无
*/
void tim_ch1ic_predivide_set(timer_chic_pdiv_t value);

/**@brief		    定时器中断配置
 *
 * @param[in]	    value  中断类型
 * @param[in]	    enable_flag  使能/禁止选择 
 * @return		    无  
*/
void tim_interrupt_config(timer_int_source_t value, enable_state_t enable_flag);

/**@brief		    定时器事件源设置
 *
 * @param[in]	    value  事件源
 * @return		    无
*/
void tim_event_source_set(timer_event_source_t value);

/**@brief		    检查指定的定时器事件标志
 *
 * @param[in]	    flag  指定的定时器事件
 * @return		    事件标志：SET或RESET
*/
bit_status_t tim_flag_status_get(timer_flag_t flag);

/**@brief		    清除指定的定时器事件标志
 *
 * @param[in]	    flag  指定的定时器事件
 * @return		    无
*/
void tim_flag_status_clear(timer_flag_t flag);

/**@brief		    定时器中断状态获取
 *
 * @param[in]	    value  定时器中断类型
 * @return		    事件标志：SET或RESET
*/
bit_status_t tim_interrupt_status_get(timer_int_source_t value);

/**@brief		    清除定时器中断状态标记
 *
 * @param[in]	    value  选定的定时器中断类型
 * @return		    无
*/
void tim_interrupt_status_clear(timer_flag_t value);

/**@brief		    定时器输入1重映射
 *
 * @param[in]	    value  选择连接到GPIO或MCO输出
 * @return		    无
*/
void tim_remap_config(timer_remap_t value);

/*@}*/ /* end of group TIM0 */

#ifdef __cplusplus
}
#endif

#endif  //__CSA37F7X_TIM_H__


/*** (C) COPYRIGHT 2020 Chipsea Technologies (Shenzhen) Corp. ***/
